﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Text.RegularExpressions;

using DataObject.Database;
using DataObject.DataAccess;
using DataObject.Helpers;

public partial class Pages_Reports_ServiceReport : System.Web.UI.Page
{
    const string url = @"/Pages/Reports/ServiceReport.aspx?ServiceID={0}&BoatID={1}&ClientType={2}&ServiceType={3}&FromDate={4:d}&ToDate={5:d}&FromServiceDate={6:d}&ToServiceDate={7:d}&SortField={8}&SortOption={9}";

    #region Fields

    private string _serviceId, _boatID, Xls;
    private int _clientType, _serviceType;
    private DateTime? _fromDate, _toDate, _fromServiceDate, _toServiceDate;
    private Guid? _providerId;

    #endregion

    #region Properties

    private int PageIndex
    {
        get
        {
            if (Request["page"] != null)
            {
                return int.Parse(Request["page"].ToString());
            }
            return 1;
        }
    }

    #endregion

    #region Events

    protected override void OnLoad(EventArgs e)
    {
        this.grv.DataBound += new EventHandler(grv_DataBound);

        if (!IsPostBack)
        {
            this.LoadBoat();
            this.LoadService();

            // Search all - default status
            this.GetQueryString();

            if (Xls == String.Empty)
            {
                this.Search();
            }
            else
            {
                this.ExportProvider();
            }
        }

        base.OnLoad(e);
    }

    protected void grv_DataBound(object sender, EventArgs e)
    {
        // -- Format --
        if (grv.Rows.Count > 0)
        {
            GridViewRow gvRow = grv.Rows[grv.Rows.Count - 1];
            gvRow.Cells[11].ForeColor = gvRow.Cells[11].Text == "Shared" ? System.Drawing.Color.Blue : System.Drawing.Color.Red;
            if (String.Compare(gvRow.Cells[11].Text, "None", true) == 0)
            {
                gvRow.BackColor = System.Drawing.Color.LightYellow;
            }
            else if (String.Compare(gvRow.Cells[11].Text, "Shared", true) == 0 && String.Compare(gvRow.Cells[6].Text, "shuttle", true) == 0)
            {
                gvRow.Cells[7].Text = gvRow.Cells[8].Text
                    = gvRow.Cells[9].Text = gvRow.Cells[10].Text
                    = String.Empty;
            }

            for (int rowIndex = grv.Rows.Count - 2;
                                               rowIndex >= 0; rowIndex--)
            {
                gvRow = grv.Rows[rowIndex];
                GridViewRow gvPreviousRow = grv.Rows[rowIndex + 1];
                // gvRow.Cells.Count
                gvRow.Cells[11].ForeColor = gvRow.Cells[11].Text == "Shared" ? System.Drawing.Color.Blue : System.Drawing.Color.Red;
                if (String.Compare(gvRow.Cells[11].Text, "None", true) == 0)
                {
                    gvRow.BackColor = System.Drawing.Color.LightYellow;
                }
                else if (String.Compare(gvRow.Cells[11].Text, "Shared", true) == 0 && String.Compare(gvRow.Cells[6].Text, "shuttle", true) == 0)
                {
                    gvRow.Cells[7].Text = gvRow.Cells[8].Text
                        = gvRow.Cells[9].Text = gvRow.Cells[10].Text
                        = String.Empty;
                }

                if (gvRow.Cells[3].Text == gvPreviousRow.Cells[3].Text)
                {
                    // Similar booking code
                    for (int cellCount = 0; cellCount < 6; cellCount++)
                    {
                        gvPreviousRow.Cells[cellCount].Text = null;
                    }
                }
            }
        }
    }

    protected void btnSearch_Click(object sender, EventArgs e)
    {
        GetOnForm();
        Response.Redirect(String.Format(url, _serviceId, _boatID, _clientType, _serviceType, _fromDate, _toDate, _fromServiceDate, _toServiceDate, null, null));
    }

    protected void btnReport_Click(object sender, EventArgs e)
    {
        this.GetQueryString();
        this.Print();
    }

    #endregion

    #region Methods

    /// <summary>
    /// Load Boats
    /// </summary>
    private void LoadBoat()
    {
        // Load Boats
        this.ddlBoat.DataSource = BoatDAO.CreateInstant().GetAllBoats();
        this.ddlBoat.DataTextField = "BoatName";
        this.ddlBoat.DataValueField = "BoatID";
        this.ddlBoat.DataBind();
    }

    /// <summary>
    /// Load Service
    /// </summary>
    private void LoadService()
    {
        // Load ddlServiceID
        this.ddlServiceID.DataSource = ServiceDAO.CreateInstant().GetAll();
        this.ddlServiceID.DataTextField = "ServiceName";
        this.ddlServiceID.DataValueField = "ServiceID";
        this.ddlServiceID.DataBind();
    }

    /// <summary>
    /// 
    /// </summary>
    private void GetQueryString()
    {
        Xls = Request["XLS"] ?? String.Empty;

        _serviceId = Request["ServiceID"] ?? String.Empty;
        _boatID = Request["BoatID"] ?? String.Empty;

        Guid providerId;

        if (null == Request["ProviderID"] || !GuidUtils.TryParse(Request["ProviderID"], out providerId))
        {
            _providerId = null;
        }
        else
        {
            _providerId = providerId;
        }

        if (null == Request["ClientType"] || !int.TryParse(Request["ClientType"], out _clientType))
        {
            _clientType = -1;
        }

        if (null == Request["ServiceType"] || !int.TryParse(Request["ServiceType"], out _serviceType))
        {
            _serviceType = -1;
        }

        DateTime fromDate, toDate, fromServiceDate, toServiceDate;

        if (!DateTime.TryParse(Request["FromDate"], System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out fromDate))
        {
            _fromDate = null;
        }
        else
        {
            _fromDate = fromDate.Date;

            this.txtFromDate.Text = fromDate.ToShortDate();
        }

        if (!DateTime.TryParse(Request["ToDate"], System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out toDate))
        {
            _toDate = null;
        }
        else
        {
            _toDate = toDate.Date;

            this.txtToDate.Text = toDate.ToShortDate();
        }

        if (!DateTime.TryParse(Request["FromServiceDate"], System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out fromServiceDate))
        {
            if (_fromDate == null)
            {
                _fromServiceDate = DateTime.Today;

                this.txtFromServiceDate.Text = DateTime.Today.ToShortDate();
            }
            else
            {
                _fromServiceDate = null;
            }
        }
        else
        {
            _fromServiceDate = fromServiceDate.Date;

            this.txtFromServiceDate.Text = fromServiceDate.ToShortDate();
        }

        if (!DateTime.TryParse(Request["ToServiceDate"], System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out toServiceDate))
        {
            if (_toDate == null)
            {
                _toServiceDate = DateTime.Today;

                this.txtToServiceDate.Text = DateTime.Today.ToShortDate();
            }
            else
            {
                _toServiceDate = null;
            }
        }
        else
        {
            _toServiceDate = toServiceDate.Date;

            this.txtToServiceDate.Text = toServiceDate.ToShortDate();
        }

        this.ddlServiceID.SelectedValue = _serviceId;
        this.ddlBoat.SelectedValue = _boatID;
        this.ddlClientType.SelectedValue = _clientType.ToString();
        this.ddlServiceType.SelectedValue = _serviceType.ToString();
    }

    /// <summary>
    /// 
    /// </summary>
    private void GetOnForm()
    {
        DateTime fromDate, toDate, fromServiceDate, toServiceDate;

        // FromDate
        if (DateTime.TryParse(txtFromDate.Text, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out fromDate))
        {
            _fromDate = fromDate;
        }
        else
        {
            _fromDate = null;
        }

        // ToDate
        if (DateTime.TryParse(txtToDate.Text, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out toDate))
        {
            _toDate = toDate;
        }
        else
        {
            _toDate = null;
        }


        // FromServiceDate
        if (DateTime.TryParse(txtFromServiceDate.Text, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out fromServiceDate))
        {
            _fromServiceDate = fromServiceDate;
        }
        else
        {
            _fromServiceDate = null;
        }

        // ToServiceDate
        if (DateTime.TryParse(txtToServiceDate.Text, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out toServiceDate))
        {
            _toServiceDate = toServiceDate;
        }
        else
        {
            _toServiceDate = null;
        }

        // Client Type
        this._clientType = Int32.Parse(this.ddlClientType.SelectedValue);
        this._serviceType = Int32.Parse(this.ddlServiceType.SelectedValue);
        this._boatID = this.ddlBoat.SelectedValue;
        this._serviceId = this.ddlServiceID.SelectedValue;
    }

    private void BuildOnGrid(out int count)
    {
        BuildOnGrid(out count, null, null);
    }

    private void BuildOnGrid(out int count, int? pageIndex, int? pageSize)
    {
        HashSet<string> hs = new HashSet<string>();
        hs.Add("DepartureDate ASC");
        hs.Add("ReservationCode ASC");
        hs.Add("OrderBy ASC");

        grv.DataSource = DataObject.DataAccess.ReservationDAO.CreateInstant().GetViewServicesReport(_fromDate, _toDate, _fromServiceDate, _toServiceDate, _clientType, _serviceType, _boatID, _serviceId, _providerId, pageIndex, pageSize, out count, hs);
        grv.DataBind();

        grdProvider.DataSource = DataObject.DataAccess.ReservationDAO.CreateInstant().GetProvider(_fromDate, _toDate, _fromServiceDate, _toServiceDate, _clientType, _serviceType, _boatID, _serviceId);
        grdProvider.DataBind();
    }

    /// <summary>
    /// Search method
    /// </summary>
    private void Search()
    {
        int count = 0;
        BuildOnGrid(out count, PageIndex, define.PageSize);

        smartPager.PageSize = define.PageSize;
        smartPager.QueryStringKey = "page";
        smartPager.RowCount = count;
        smartPager.UrlFormatString = String.Concat(String.Format(url, _serviceId, _boatID, _clientType, _serviceType, _fromDate, _toDate, _fromServiceDate, _toServiceDate, null, null), "&page={0}");
        smartPager.Visible = count > define.PageSize;
    }

    /// <summary>
    /// Print method
    /// </summary>
    private void Print()
    {
        int count = 0;
        BuildOnGrid(out count);

        var form = new System.Web.UI.HtmlControls.HtmlForm();
        form.Controls.Add(grv);

        string attachment = String.Format("attachment; filename=accountant{0:yyyyMMdd}.xls", DateTime.Now);
        Response.ClearContent();
        Response.AddHeader("content-disposition", attachment);
        Response.ContentType = "application/ms-excel";
        Response.Charset = String.Empty;
        Response.ContentEncoding = System.Text.Encoding.Unicode;
        Response.BinaryWrite(System.Text.Encoding.Unicode.GetPreamble());

        System.IO.StringWriter stw = new System.IO.StringWriter();
        HtmlTextWriter htextw = new HtmlTextWriter(stw);
        this.Controls.Add(form);
        form.RenderControl(htextw);

        Response.Write(stw.ToString());
        Response.End();
    }

    private void ExportProvider()
    {
        int count = 0;
        HashSet<string> hs = new HashSet<string>();
        hs.Add("DepartureDate ASC");
        hs.Add("ReservationCode ASC");
        hs.Add("ServiceID ASC");

        IList<ViewServicesReport> services = DataObject.DataAccess.ReservationDAO.CreateInstant().GetViewServicesReport(_fromDate, _toDate, _fromServiceDate, _toServiceDate, _clientType, _serviceType, _boatID, _serviceId, _providerId, null, null, out count, hs);

        if (null != services && services.Count > 0)
        {
            string filename = "pages/Reports/template/sendvendor.htm";
            string filePath = HttpContext.Current.Server.MapPath(HttpContext.Current.Request.ApplicationPath.Replace("/", "\\")) + "\\" + filename;
            string body = Helper.ReadTemplateFile(filePath);

            DateTime date = _fromDate ?? _toDate ?? DateTime.Today;
            this.SplitDetail(body, services.First().ProviderName, date.Month, date.Year, services);
        }
    }

    /// <summary>
    /// Split method
    /// </summary>
    private void SplitDetail(string body, string providerName, int month, int year, IEnumerable<ViewServicesReport> services)
    {
        body = body.Replace("[Month]", month.ToString());
        body = body.Replace("[Year]", year.ToString());
        body = body.Replace("[ProviderName]", providerName);
        body = body.Replace("[SubTotal]", (services.Sum(x => x.Amount) ?? 0).ToString("#,##0.##"));

        var form = new System.Web.UI.HtmlControls.HtmlForm();
        form.InnerHtml = FillDetails(body, "loop1", services,
            "BoatID", "DepartureDate", "RouteName", "ReservationCode", "GuestID", "NumOfPax", "UnitPrice", "Amount");

        string attachment = String.Format("attachment; filename=ServicesOf{0}.xls", providerName.ToFilename());
        Response.ClearContent();
        Response.AddHeader("content-disposition", attachment);
        Response.ContentType = "application/ms-excel";
        Response.Charset = String.Empty;
        Response.ContentEncoding = System.Text.Encoding.Unicode;
        Response.BinaryWrite(System.Text.Encoding.Unicode.GetPreamble());

        System.IO.StringWriter stw = new System.IO.StringWriter();
        HtmlTextWriter htextw = new HtmlTextWriter(stw);
        this.Controls.Add(form);
        form.RenderControl(htextw);

        Response.Write(stw.ToString());
        Response.End();
    }

    private string FillDetails(string template, string loopID, IEnumerable<ViewServicesReport> collection, params string[] columns)
    {
        string content = String.Empty;

        template = Regex.Replace(template, "\r\n", String.Empty);

        Regex reg = new Regex(String.Concat("<!--", loopID, "-->(.*?)<!--/", loopID, "-->"));
        if (reg.IsMatch(template))
        {
            var htmlRow = reg.Match(template).Groups[1].Value;
            var rowTemplate = htmlRow;

            int length = collection.Count();
            for (int i = 0; i < length; i++)
            {
                foreach (var c in columns)
                {
                    var item = collection.ElementAt(i);
                    var value = item.GetType().GetProperty(c).GetValue(item, null);
                    if (null == value)
                    {
                        htmlRow = htmlRow.Replace("[#" + c + "]", String.Empty);
                    }
                    else
                    {
                        htmlRow = htmlRow.Replace("[#" + c + "]", value.ToString());
                    }
                }

                if (i == length - 1)
                    continue;

                htmlRow += rowTemplate;
            }

            content = reg.Replace(template, htmlRow);
        }

        return content;
    }

    #endregion

}